package zhxt.helmet.service;

import org.bytedeco.javacv.FFmpegFrameGrabber;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import zhxt.helmet.pojo.Result;
import zhxt.helmet.utils.CameraThread;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

@Service
public class CameraThreadManager {
    //Map<cameraId, CameraThread>
    private final Map<Integer, CameraThread> cameraThreads = new ConcurrentHashMap<>();//保存摄像头线程
    //线程池
    private final ExecutorService executorService = Executors.newCachedThreadPool();//线程池
    //记录每个用户已订阅的摄像头 Map<userId, List<cameraId>>
    private final Map<Integer, List<Integer>> userSelectedCamera = new ConcurrentHashMap<>();
    @Autowired
    private ResultService resultService;

    //用户获取已选摄像头, 用于页面初始时,在选择摄像头的文本框显示
    public List<Integer> getUserSelectedCamera(int userId) {
        return userSelectedCamera.getOrDefault(userId, new ArrayList<>());
    }
    //订阅
    public void subscribe(List<Integer> selectList, int userId) throws FFmpegFrameGrabber.Exception {
        // 获取用户已订阅的摄像头列表，如果为 null 则返回一个空列表
        List<Integer> userSelectedList = userSelectedCamera.getOrDefault(userId, new ArrayList<>());
        //订阅
        List<Integer> newCameras = new ArrayList<>(selectList);
        newCameras.removeAll(userSelectedList);//新增订阅
        addUserToCameras(newCameras, userId);
        //退订
        List<Integer> outdatedCameras = new ArrayList<>(userSelectedList);
        outdatedCameras.removeAll(selectList);//移除未订阅
        removeUserFromCameras(outdatedCameras, userId);
        //更新
        userSelectedCamera.put(userId, selectList);
    }

    //用户订阅一系列摄像头
    private void addUserToCameras(  List<Integer> cameras,int userId) throws FFmpegFrameGrabber.Exception {
        for (Integer cameraId : cameras) {
            addUserToCamera(cameraId, userId);
        }
    }
    //添加用户摄像头线程
    private void addUserToCamera(int cameraId, int userId) throws FFmpegFrameGrabber.Exception {
        CameraThread cameraThread = cameraThreads.get(cameraId);
        if (cameraThread == null) {//此摄像头还未创建线程
            cameraThread = new CameraThread(cameraId, this);//创建线程
            System.out.println(cameraId + " 创建线程");
            cameraThread.addUser(userId);//记录用户
            cameraThreads.put(cameraId, cameraThread);//保存摄像头线程
            executorService.execute(cameraThread);//执行线程
        }
        else cameraThread.addUser(userId);//记录用户
    }
    //用户取消订阅摄像头
    private void removeUserFromCameras(List<Integer> cameras, int userId) throws FFmpegFrameGrabber.Exception {
        for (Integer cameraId : cameras) {
            removeUserFromCamera(cameraId, userId);
        }
    }
    //移除摄像头用户
    private void removeUserFromCamera(int cameraId, int userId) throws FFmpegFrameGrabber.Exception {
        CameraThread cameraThread = cameraThreads.get(cameraId);//找到线程
        if (cameraThread != null) {//找到了（还有人用这个摄像头）
            cameraThread.removeUser(userId);//用户取消订阅，用户为0会关闭识别服务
            if (cameraThread.getUsers().isEmpty()) {//无用户订阅
                cameraThreads.remove(cameraId);//从 Map 中移除线程
            }
        }
    }

    //数据库保存识别结果
    public void insertResult(Result result) {
        resultService.insertResult(result);
    }
    public void insertResults(List<Result> results){
        resultService.insertResults(results);
    }
}